package com.utp.freemarker.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;

import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * @author Arnold Yand
 * @since Mar 21, 20174:30:56 PM
 * @summary com.utp.freemarker.service.FreemarkerService.java
 */
@Component("freemarkerService")
public final class FreemarkerService {

    private Configuration configuration;
    private Logger log = LoggerFactory.getLogger(this.getClass().getName());

    public FreemarkerService() throws IOException {
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        log.info("start loading template...");
        Resource[] resources = resolver.getResources("com/utp/freemarker/ftl/*.vm");

        StringTemplateLoader templateLoader = new StringTemplateLoader();
        String content = null;
        for (Resource res : resources) {
            content = this.getTemplateContent(res.getInputStream());
            templateLoader.putTemplate(res.getFilename(), content);
            log.info("loaded template : " + res.getFilename());
        }
        log.info(resources.length + " template loaded in all.");

        configuration = new Configuration(Configuration.getVersion());
        configuration.setObjectWrapper(new DefaultObjectWrapper(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS));
        configuration.setTemplateLoader(templateLoader);
        configuration.setNumberFormat("#");
    }
    
    public String buildView(Map<String, Object> root, String templatePath) throws IOException, TemplateException {
        Template tpl = configuration.getTemplate(templatePath + ".vm");
        Writer out = new StringWriter();
        tpl.process(root, out);
        String content = out.toString();
        return content;
    }

    private String getTemplateContent(InputStream is) {

        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder strBuf = new StringBuilder("");

        try {
            String line = null;
            while ((line = reader.readLine()) != null) {
                strBuf.append(line + "\n");
            }
        } catch (IOException e) {
            log.error("convert input stream occasion exception. ", e);
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                log.error("close input stream occasion exception. ", e);
            }
        }

        return strBuf.toString();
    }

}
